import { IReq, IRes } from "@src/constants/response";
import HttpStatusCodes from "@src/constants/HttpStatusCodes";
import { Response, Request, NextFunction } from 'express';

import userService from "@src/services/user";
import crypto from 'crypto';
import { checkSchema, Schema, validationResult } from "express-validator";
import validate from "@src/util/validate";
import type { User } from "@src/db/schema/users";
import { RouteError } from "@src/util/route-errors";
import passport from '@src/util/passport'
import debug from "debug";

const log = debug('app:user-controller');

/* ---------------------------------- TYPE ---------------------------------- */
type Req = Request<any, any, User>
type Res = Response<any, any>
type Next = NextFunction
/* ------------------------------- Validators ------------------------------- */

export const loginScheme: Schema = {
  username: {
    in: ['body'],
    isString: {
      errorMessage: 'name 必须是字符串'
    },
    notEmpty: {
      errorMessage: 'name 不能为空'
    },
    trim: true,
    isLength: {
      options: { min: 2, max: 50 },
      errorMessage: 'name 长度必须在2-50个字符之间'
    }
  },
  password: {
    in: ['body'],
    isString: {
      errorMessage: 'password 必须是字符串'
    },
    notEmpty: {
      errorMessage: 'password 不能为空'
    },
    isLength: {
      options: { min: 6 },
      errorMessage: 'password 长度至少6个字符'
    }
  },
};

export const registerScheme: Schema = {
  name: {
    in: ['body'],
    isString: {
      errorMessage: 'name 必须是字符串'
    },
    notEmpty: {
      errorMessage: 'name 不能为空'
    },
    trim: true,
    isLength: {
      options: { min: 2, max: 50 },
      errorMessage: 'name 长度必须在2-50个字符之间'
    }
  },
  password: {
    in: ['body'],
    isString: {
      errorMessage: 'password 必须是字符串'
    },
    notEmpty: {
      errorMessage: 'password 不能为空'
    },
    isLength: {
      options: { min: 6 },
      errorMessage: 'password 长度至少6个字符'
    }
  },
  email: {
    in: ['body'],
    isEmail: {
      errorMessage: 'email 必须是邮箱'
    }
  },
  role_id: {
    in: ['body'],
    isInt: {
      errorMessage: 'role_id 必须是整数'
    },
  }
};

/* -------------------------------- Function -------------------------------- */

async function login(req: Req, res: Res, next: Next) {
  const validationErrors = await validate(req, res, loginScheme);

  if (validationErrors) {
    return res.render('login', {
      title: 'Login',
      errors: validationErrors,
    });
  }

  passport.authenticate('local', function (err: any, user: any, info: any) {
    if (err) {
      return next(err);
    }

    log('user', user);

    if (!user) {
      // 认证失败，重定向到登录页面并显示错误信息
      return res.render('login', {
        title: 'Login',
        errors: [{ msg: info?.message || "登录失败" }],
      });
    }


    // 重新调用 login 接口，重新生成 session ID
    req.login(user, function (err) {
      if (err) return next(err);

      req.session.save((err) => {
        if (err) return next(err);
        res.redirect('/');
      });
    });

  })(req, res, next);
}

async function register(req: Req, res: Res, next: Next) {

  log('req.body', req.body);
  const { name, password, email, role_id } = req.body;

  // 使用 registerScheme 进行校验
  const validationErrors = await validate(req, res, registerScheme);

  if (validationErrors) {
    // return res.status(HttpStatusCodes.BAD_REQUEST).json({
    //   success: false,
    //   message: '注册信息校验失败',
    //   errors: validationErrors
    // });

    return res.render('register', {
      title: 'Register',
      errors: validationErrors,
      formData: { name } // 保留用户输入的数据（不包括密码）
    });
  }

  try {

    // 生成随机 salt（Buffer）
    const salt = crypto.randomBytes(16);

    // 使用 pbkdf2 加密密码（返回 Buffer）
    const hashedPasswordBuffer = crypto.pbkdf2Sync(password, salt, 310000, 32, 'sha256');

    // ⚠️ 重要：将 Buffer 转换为十六进制字符串，才能存入数据库
    const hashedPassword = hashedPasswordBuffer.toString('hex'); // 64个字符的十六进制字符串
    const saltString = salt.toString('hex'); // 32个字符的十六进制字符串

    // 调用service注册用户
    const { id } = await userService.register({
      name,
      password: hashedPassword,
      salt: saltString,
      email,
      role_id: Number(role_id),
    });


    const user = {
      id,
      name,
      role_id: Number(role_id),
    };

    // 调用 passport 登录
    req.login(user, function (err) {
      if (err) { return next(err); }
      req.session.save((err) => {
        if (err) return next(err);
        res.redirect('/'); // 登录后跳转主页
      });
    });

  } catch (error: any) {
    // DrizzleQueryError 的错误结构：
    // error.message - Drizzle 的错误消息
    // error.cause - 原始的 MySQL 错误对象

    log('error.cause', error.cause);
    const routeError = new RouteError(HttpStatusCodes.INTERNAL_SERVER_ERROR, error.cause);
    next(routeError);
  }
}



export default {
  register,
  login,
};
